package utility

import (
	"context"
	"errors"
	"gin_demo/internal/consts"
	"net/url"
	"time"

	"github.com/minio/minio-go/v7"
	"github.com/minio/minio-go/v7/pkg/credentials"
)

/*初始化minio*/
func InitMinio() *minio.Client {
	minioClent, err := minio.New(consts.App.Configuration.Minio.EndPoint+":"+consts.App.Configuration.Minio.Port, &minio.Options{
		Creds:  credentials.NewStaticV4(consts.App.Configuration.Minio.AccessKey, consts.App.Configuration.Minio.SecretKey, ""),
		Secure: consts.App.Configuration.Minio.UseSSL,
	})
	if err != nil {
		consts.App.Log.Error(err.Error())
	}
	return minioClent
}

/*创建桶*/
func CreateMinioBucket(BucketName string) error {
	// 配置桶的S3策略
	policy := `{"Version": "2012-10-17","Statement": [{"Action": ["s3:GetObject"],"Effect": "Allow","Principal": {"AWS": ["*"]},"Resource": ["arn:aws:s3:::mymusic/*"],"Sid": ""}]}`

	err := consts.App.MinioClient.MakeBucket(context.Background(), BucketName, minio.MakeBucketOptions{
		Region:        consts.App.Configuration.Minio.Location,
		ObjectLocking: true,
	})
	if err != nil {
		b, err := consts.App.MinioClient.BucketExists(context.Background(), BucketName)
		if err == nil && b {
			// 桶已存在无需创建
			if err = consts.App.MinioClient.SetBucketPolicy(context.Background(), BucketName, policy); err != nil { // 设置通访问策略
				consts.App.Log.Error(err.Error())
				e := errors.New("存储池策略配置异常")
				return e
			}
		} else {
			consts.App.Log.Error(err.Error())
			e := errors.New("存储池初始化出现异常")
			return e
		}
	} else {
		err := consts.App.MinioClient.SetBucketPolicy(context.Background(), BucketName, policy)
		if err != nil {
			consts.App.Log.Error(err.Error())
			e := errors.New("存储池策略配置异常")
			return e
		}
	}
	return nil
}

/*上传文件*/
func UploadFile(objectName, filePath, bucketName, contentType string) (string, error) {
	//调用创建桶函数
	CreateMinioBucket(bucketName)
	_, err := consts.App.MinioClient.FPutObject(context.Background(), bucketName, objectName, filePath, minio.PutObjectOptions{
		ContentType: contentType,
	})
	if err != nil {
		consts.App.Log.Error(err.Error())
		e := errors.New("文件上传失败")
		return "", e
	}
	reqParams := make(url.Values)
	presignedURL, err := consts.App.MinioClient.PresignedGetObject(context.Background(), bucketName, objectName, time.Second*24*60*60, reqParams)
	if err != nil {
		consts.App.Log.Error(err.Error())
		e := errors.New("文件上传信息获取失败")
		return "", e
	} else {
		link := presignedURL.Scheme + "://" + presignedURL.Host + presignedURL.Path
		return link, nil
	}
}
